﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SharpSoda.Message
{
    public class MessageHandler<T> : IMessageHandler where T : JsonMessage
    {
        public Type GetMessageType()
        {
            return typeof(T);
        }

        public virtual TaskFactory GetTaskExecutor(T msg)
        {
            return null;
        }

        public virtual object Handle(object data)
        {
            if (data != null && data is MessageSessionData)
            {
                MessageSessionData sessionData = data as MessageSessionData;
                IMessageSession session = sessionData.Session;
                string message = sessionData.Message;
                if (message != null && message.Length > 0)
                {
                    T msg = JsonHelper.FromString<T>(message);
                    if (msg != null)
                    {
                        if (session != null)
                        {
                            ProcessTask(session, msg, sessionData.Data);
                            return "";
                        }
                        else
                        {
                            if (sessionData.Data == null || sessionData.Data.Length <= 0) return HandleMessage(msg);
                            else return HandleMessage(msg, sessionData.Data);
                        }
                    }
                }
            }
            return "Invalid message";
        }

        public virtual void ProcessTask(IMessageSession session, T msg, byte[] data)
        {
            TaskFactory executor = null;
            if (msg != null) executor = GetTaskExecutor(msg);
            //if (executor == null) executor = Task.Factory;
            if (executor != null)
            {
                executor.StartNew(() =>
                {
                    if (data == null || data.Length <= 0) HandleMessage(session, msg);
                    else HandleMessage(session, msg, data);
                });
            }
            else
            {
                if (data == null || data.Length <= 0) HandleMessage(session, msg);
                else HandleMessage(session, msg, data);
            }
        }

        public virtual void HandleMessage(IMessageSession session, T msg)
        {
            return;
        }

        public virtual void HandleMessage(IMessageSession session, T msg, byte[] data)
        {
            return;
        }

        public virtual object HandleMessage(T msg)
        {
            return "Invalid message";
        }

        public virtual object HandleMessage(T msg, byte[] data)
        {
            return "Invalid message";
        }
    }
}
